using UnityEngine;
using System.Collections;

[RequireComponent(typeof(MeshCollider))]
[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(MeshRenderer))]
public class Square : MonoBehaviour
{

    private Mesh myMesh;
	private Vector3[] meshVertices;
	private Vector2[] meshUV;
	private int[] meshFaceIndex;
    private string name;
	private string textureName;

    public Square()
    {

    }

    public void Build(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4,
                    Vector2 uv1, Vector2 uv2, Vector2 uv3, Vector2 uv4,
                    string TextureName, string Name)
    {
        Debug.Log("Build Called");
        meshVertices = new Vector3[4];
        meshVertices[0] = p1;
        meshVertices[1] = p2;
        meshVertices[2] = p3;
        meshVertices[3] = p4;

        meshUV = new Vector2[4];
        meshUV[0] = uv1;
        meshUV[1] = uv2;
        meshUV[2] = uv3;
        meshUV[3] = uv4;

        meshFaceIndex = new int[6];
        meshFaceIndex[0] = 0;
        meshFaceIndex[1] = 1;
        meshFaceIndex[2] = 2;
        meshFaceIndex[3] = 2;
        meshFaceIndex[4] = 3;
        meshFaceIndex[5] = 0;
        name = Name;
		textureName = TextureName;
		
		MeshFilter meshFilter = GetComponent<MeshFilter>();
        if (meshFilter == null)
        {
            Debug.LogError("MeshFilter not found!");
            return;
        }

        myMesh = meshFilter.sharedMesh;
        if (myMesh == null) myMesh = new Mesh();
        meshFilter.sharedMesh = myMesh;
        //myMesh.Clear();
        //GetComponent<MeshFilter>().mesh = myMesh;
        myMesh.vertices = meshVertices;
        myMesh.uv = meshUV;
        myMesh.triangles = meshFaceIndex;
        myMesh.RecalculateNormals();
        myMesh.RecalculateBounds();
        renderer.material.mainTexture = AssetManager.GetInstance().GetTexture(textureName);
        myMesh.Optimize();
    }

    public bool intersect(Square cutZone)
    {
        Vector3 cutZoneCenter = cutZone.transform.position + new Vector3(0.5f, 0.5f, 0.0f);
        Vector3 squareBottomLeft = meshVertices[0];

        Vector3 p1, p2;
        p1 = new Vector3(squareBottomLeft.x, squareBottomLeft.y, squareBottomLeft.z);
        p2 = new Vector3(squareBottomLeft.x + 1, squareBottomLeft.y + 1, squareBottomLeft.z);

        p1 = transform.parent.TransformPoint(p1);
        p2 = transform.parent.TransformPoint(p2);

        if (cutZoneCenter.x >= Mathf.Min(p1.x, p2.x)
            && cutZoneCenter.x <= Mathf.Max(p1.x, p2.x)
            && cutZoneCenter.y >= Mathf.Min(p1.y, p2.y)
            && cutZoneCenter.y <= Mathf.Max(p1.y, p2.y)
            )
        {
            return true;
        }

        return false;
    }

    public void destroy()
    {
        MeshFilter meshFilter = GetComponent<MeshFilter>();
        myMesh.Clear();
        myMesh.RecalculateNormals();
        myMesh.RecalculateBounds();
        myMesh.Optimize();
    }

    public void rebuild()
    {
        MeshFilter meshFilter = GetComponent<MeshFilter>();
        if (meshFilter == null)
        {
            Debug.LogError("MeshFilter not found!");
            return;
        }

        myMesh = meshFilter.sharedMesh;
        if (myMesh == null) myMesh = new Mesh();
        meshFilter.sharedMesh = myMesh;
        //myMesh.Clear();
        //GetComponent<MeshFilter>().mesh = myMesh;
        myMesh.vertices = meshVertices;
        myMesh.uv = meshUV;
        myMesh.triangles = meshFaceIndex;
        myMesh.RecalculateNormals();
        myMesh.RecalculateBounds();
        renderer.material.mainTexture = AssetManager.GetInstance().GetTexture(textureName);
        myMesh.Optimize();
    }

    public void cut(Vector3 cutZonePosition, int startIndex)
    {
        Vector3 nextVertice = getNextMeshVertice(startIndex);
        Vector3 lastVertice = getPreviousMeshVertice(startIndex);

        // Vertices
        Vector3[] meshVertices2 = new Vector3[8];
        meshVertices2[0] = meshVertices[startIndex];
        meshVertices2[1] = new Vector3(cutZonePosition.x, meshVertices[startIndex].y, meshVertices[startIndex].z);
        meshVertices2[2] = nextVertice;
        meshVertices2[3] = new Vector3(nextVertice.x, cutZonePosition.y, meshVertices[startIndex].z);
        meshVertices2[4] = new Vector3(cutZonePosition.x, cutZonePosition.y, meshVertices[startIndex].z);
        meshVertices2[5] = new Vector3(cutZonePosition.x, lastVertice.y, meshVertices[startIndex].z);
        meshVertices2[6] = lastVertice;
        meshVertices2[7] = new Vector3(meshVertices[startIndex].x, cutZonePosition.y, meshVertices[startIndex].z);

        // UV
        //Vector2[] meshUV2 = new Vector2[4];
        //meshUV2[0] = meshUV[0];
        //meshUV2[1] = meshUV[1];
        //meshUV2[2] = meshUV[2];
        //meshUV2[3] = meshUV[3];

        //meshUV2[4] = new Vector2((first.x + 1) / 2.0f, (first.y + 1) / 2.0f);
        //meshUV2[5] = new Vector2((second.x + 1) / 2.0f, (second.y + 1) / 2.0f);
        //meshUV2[6] = new Vector2((third.x + 1) / 2.0f, (third.y + 1) / 2.0f);
        //meshUV2[7] = new Vector2((fourth.x + 1) / 2.0f, (fourth.y + 1) / 2.0f);

        //meshUV = meshUV2;

        // Indices
        meshFaceIndex = new int[18];
        meshFaceIndex[0] = 0;
        meshFaceIndex[1] = 1;
        meshFaceIndex[2] = 4;
        meshFaceIndex[3] = 4;
        meshFaceIndex[4] = 7;
        meshFaceIndex[5] = 0;

        meshFaceIndex[6] = 1;
        meshFaceIndex[7] = 2;
        meshFaceIndex[8] = 3;
        meshFaceIndex[9] = 3;
        meshFaceIndex[10] = 4;
        meshFaceIndex[11] = 1;

        meshFaceIndex[12] = 7;
        meshFaceIndex[13] = 4;
        meshFaceIndex[14] = 5;
        meshFaceIndex[15] = 5;
        meshFaceIndex[16] = 6;
        meshFaceIndex[17] = 7;

        MeshFilter meshFilter = GetComponent<MeshFilter>();
        myMesh = meshFilter.sharedMesh;
        myMesh.Clear();
        myMesh.vertices = meshVertices2;
        //myMesh.uv = meshUV2;
        myMesh.triangles = meshFaceIndex;
        myMesh.RecalculateNormals();
        myMesh.RecalculateBounds();
        myMesh.Optimize();
    }

    private Vector3 getNextMeshVertice(int index)
    {
        return meshVertices[(index + 1) % meshVertices.Length];
    }

    private Vector3 getPreviousMeshVertice(int index)
    {
        return meshVertices[(index - 1 + meshVertices.Length) % meshVertices.Length];
    }

    public Vector3[] getMeshVertices()
    {
        return meshVertices;
    }

	// Use this for initialization
	void Start () 
    {
        Debug.Log("Start Called");
	}
	
	// Update is called once per frame
	void Update () {
	
	}
}
